package org.example.xsda.service;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.example.xsda.common.PageResult;
import org.example.xsda.dto.ApprovalDTO;
import org.example.xsda.dto.ApprovalProcessDTO;
import org.example.xsda.dto.StudentApplyDTO;
import org.example.xsda.entity.*;
import org.example.xsda.exception.BusinessException;
import org.example.xsda.mapper.*;
import org.example.xsda.vo.ApprovalDetailVO;
import org.example.xsda.vo.ApprovalVO;
import org.example.xsda.vo.FileInfoVO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ApprovalService {
    
    @Resource
    private ApprovalMapper approvalMapper;
    
    @Resource
    private StudentMapper studentMapper;
    
    @Resource
    private SysUserMapper userMapper;
    
    @Resource
    private MessageService messageService;
    
    @Resource
    private StudentStatusChangeMapper statusChangeMapper;
    
    @Resource
    private ClassesMapper classesMapper;
    
    @Resource
    private DeptMapper deptMapper;
    
    @Resource
    private FileService fileService;
    
    @Resource
    private RedisService redisService;
    
    // 缓存key前缀
    private static final String CACHE_KEY_APPROVAL_DETAIL = "approval:detail:";
    
    public PageResult<ApprovalVO> getApprovalPage(Integer current, Integer size, Integer applyType, Integer status) {
        Page<Approval> page = new Page<>(current, size);
        
        LambdaQueryWrapper<Approval> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(applyType != null, Approval::getApplyType, applyType);
        wrapper.eq(status != null, Approval::getStatus, status);
        wrapper.eq(status != null, Approval::getStatus, status);
        //approval.getCurrentApproverId()
        wrapper.orderByDesc(Approval::getApplyTime);
        
        IPage<Approval> approvalPage = approvalMapper.selectPage(page, wrapper);
        List<ApprovalVO> voList = convertToVO(approvalPage.getRecords());
        
        return new PageResult<>(approvalPage.getTotal(), voList);
    }
    
    @Transactional(rollbackFor = Exception.class)
    public void approve(ApprovalDTO dto) {
        Approval approval = approvalMapper.selectById(dto.getId());
        if (approval == null) {
            throw new RuntimeException("审批记录不存在");
        }
        
        if (approval.getStatus() != 0) {
            throw new RuntimeException("该申请已处理");
        }
        
        Long approverId = StpUtil.getLoginIdAsLong();
        List<String> roles = StpUtil.getRoleList();
        
        //  权限校验：根据审批级别检查用户角色
        Integer currentLevel = approval.getApprovalLevel() != null ? approval.getApprovalLevel() : 1;

        if (currentLevel == 1) {
            // Level 1 初审：只有教师可以审批
            if (!roles.contains("teacher") ) {
                throw new BusinessException("初审只能由教师进行");
            }
            if(approval.getCurrentApproverId()!= approverId){
                throw new BusinessException("您不是当前指定当前教师审核");
            }
        } else if (currentLevel == 2) {
            // Level 2 终审：只有管理员可以审批
            if (!roles.contains("admin")) {
                throw new BusinessException("终审只能由管理员进行");
            }
        }
        
        approval.setRemark(dto.getRemark());
        
        // 根据审批级别决定流程
        if (approval.getApprovalLevel() == null || approval.getApprovalLevel() == 1) {
            // Level 1：班主任初审通过，流转到Level 2
            approval.setApprovalLevel(2);
            approval.setCurrentApproverId(null); // 教务处（管理员角色）
            // status 保持为 0（待审批）
            
            // 通知管理员有新的审批
            messageService.sendMessageToRole(
                "admin",
                "approval",
                "新的审批待处理",
                "班主任已初审通过申请，请进行终审。",
                approval.getId()
            );
            
            // 通知学生初审已通过
            Student student = studentMapper.selectById(approval.getStudentId());
            if (student != null && student.getUserId() != null) {
                messageService.sendMessage(
                    student.getUserId(),
                    "approval",
                    "审批进度更新",
                    "您的申请班主任已初审通过，正在等待教务处终审。审批意见：" + (dto.getRemark() != null ? dto.getRemark() : "无"),
                    approval.getId()
                );
            }
            
            log.info("初审通过，流转到终审：approvalId={}, approverId={}", approval.getId(), approverId);
            
        } else if (approval.getApprovalLevel() == 2) {
            // Level 2：教务处终审通过，申请完成
            approval.setStatus(1); // 已通过
            approval.setApproverId(approverId);
            approval.setApproveTime(LocalDateTime.now());
            
            // 自动更新学生状态
            updateStudentStatus(approval);
            
            // 记录异动历史
            recordStatusChange(approval);
            
            // 通知学生申请已通过
            Student student = studentMapper.selectById(approval.getStudentId());
            if (student != null && student.getUserId() != null) {
                messageService.sendMessage(
                    student.getUserId(),
                    "approval",
                    "申请审批通过",
                    "恭喜！您的申请已审批通过。审批意见：" + (dto.getRemark() != null ? dto.getRemark() : "无"),
                    approval.getId()
                );
            }
            
            log.info("终审通过，审批完成：approvalId={}, approverId={}", approval.getId(), approverId);
        }
        
        approvalMapper.updateById(approval);
        
        // 清除审批详情缓存
        redisService.delete(CACHE_KEY_APPROVAL_DETAIL + approval.getId());
    }
    
    @Transactional(rollbackFor = Exception.class)
    public void reject(ApprovalDTO dto) {
        Approval approval = approvalMapper.selectById(dto.getId());
        if (approval == null) {
            throw new RuntimeException("审批记录不存在");
        }
        
        if (approval.getStatus() != 0) {
            throw new RuntimeException("该申请已处理");
        }
        
        if (dto.getRemark() == null || dto.getRemark().trim().isEmpty()) {
            throw new RuntimeException("拒绝原因不能为空");
        }
        
        approval.setStatus(2);
        approval.setRemark(dto.getRemark());
        approval.setApproveTime(LocalDateTime.now());
        approval.setApproverId(StpUtil.getLoginIdAsLong());
        approvalMapper.updateById(approval);
        
        // 清除审批详情缓存
        redisService.delete(CACHE_KEY_APPROVAL_DETAIL + approval.getId());
        
        Student student = studentMapper.selectById(approval.getStudentId());
        if (student != null && student.getUserId() != null) {
            messageService.sendMessage(
                student.getUserId(),
                "approval",
                "您的申请被拒绝",
                "您提交的申请未通过审批。拒绝原因：" + dto.getRemark(),
                approval.getId()
            );
        }
    }
    
    public Map<String, Long> getStatistics() {
        Map<String, Long> stats = new HashMap<>();
        
        LambdaQueryWrapper<Approval> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Approval::getStatus, 0);
        stats.put("pendingCount", approvalMapper.selectCount(wrapper));
        
        wrapper.clear();
        wrapper.eq(Approval::getStatus, 1);
        stats.put("approvedCount", approvalMapper.selectCount(wrapper));
        
        wrapper.clear();
        wrapper.eq(Approval::getStatus, 2);
        stats.put("rejectedCount", approvalMapper.selectCount(wrapper));
        
        stats.put("totalCount", approvalMapper.selectCount(null));
        
        return stats;
    }
    
    private List<ApprovalVO> convertToVO(List<Approval> approvalList) {
        if (approvalList == null || approvalList.isEmpty()) {
            return new ArrayList<>();
        }
        
        List<Long> studentIds = approvalList.stream()
            .map(Approval::getStudentId)
            .distinct()
            .collect(Collectors.toList());
        
        List<Student> students = studentMapper.selectBatchIds(studentIds);
        Map<Long, Student> studentMap = students.stream()
            .collect(Collectors.toMap(Student::getId, s -> s));
        
        List<Long> studentUserIds = students.stream()
            .map(Student::getUserId)
            .filter(Objects::nonNull)
            .distinct()
            .collect(Collectors.toList());
        
        Map<Long, SysUser> studentUserMap = new HashMap<>();
        if (!studentUserIds.isEmpty()) {
            List<SysUser> studentUsers = userMapper.selectBatchIds(studentUserIds);
            studentUserMap = studentUsers.stream()
                .collect(Collectors.toMap(SysUser::getId, u -> u));
        }
        
        List<Long> approverIds = approvalList.stream()
            .map(Approval::getApproverId)
            .filter(Objects::nonNull)
            .distinct()
            .collect(Collectors.toList());
        
        Map<Long, SysUser> approverMap = new HashMap<>();
        if (!approverIds.isEmpty()) {
            List<SysUser> approvers = userMapper.selectBatchIds(approverIds);
            approverMap = approvers.stream()
                .collect(Collectors.toMap(SysUser::getId, u -> u));
        }
        
        List<ApprovalVO> voList = new ArrayList<>();
        for (Approval approval : approvalList) {
            ApprovalVO vo = new ApprovalVO();
            BeanUtils.copyProperties(approval, vo);
            
            // 设置申请类型名称
            vo.setSubTypeName(getSubTypeName(approval.getSubType()));
            
            // 设置当前层级名称
            vo.setApprovalLevelName(getApprovalLevelName(approval.getApprovalLevel()));
            
            Student student = studentMap.get(approval.getStudentId());
            if (student != null) {
                vo.setStudentNo(student.getStudentNo());
                if (student.getUserId() != null) {
                    SysUser studentUser = studentUserMap.get(student.getUserId());
                    if (studentUser != null) {
                        vo.setStudentName(studentUser.getRealName());
                    }
                }
            }
            
            if (approval.getApproverId() != null) {
                SysUser approver = approverMap.get(approval.getApproverId());
                if (approver != null) {
                    vo.setApproverName(approver.getRealName());
                }
            }
            
            // 计算附件数量
            if (approval.getAttachmentIds() != null && !approval.getAttachmentIds().isEmpty()) {
                String[] fileIds = approval.getAttachmentIds().split(",");
                vo.setAttachmentCount(fileIds.length);
            } else {
                vo.setAttachmentCount(0);
            }
            
            voList.add(vo);
        }
        
        return voList;
    }
    
    // ========== 学生异动申请相关方法 ==========
    
    /**
     * 学生提交异动申请
     */
    @Transactional(rollbackFor = Exception.class)
    public Long submitStudentApply(StudentApplyDTO dto) {
        // 1. 获取当前登录用户ID
        Long userId = StpUtil.getLoginIdAsLong();
        
        // 2. 根据userId查找student记录
        LambdaQueryWrapper<Student> studentWrapper = new LambdaQueryWrapper<>();
        studentWrapper.eq(Student::getUserId, userId);
        Student student = studentMapper.selectOne(studentWrapper);
        
        if (student == null) {
            throw new BusinessException("未找到学生信息，请联系管理员创建学生档案");
        }
        
        // 3. 使用查找到的student.id
        Long studentId = student.getId();
        
        // 创建审批记录
        Approval approval = new Approval();
        approval.setStudentId(studentId);
        approval.setApplyType(1); // 1-学籍异动
        approval.setSubType(dto.getSubType());
        approval.setContent(dto.getContent());
        approval.setAttachmentIds(dto.getAttachmentIds());
        approval.setAttachmentUrl(dto.getAttachmentUrl());
        approval.setTargetClassId(dto.getTargetClassId());
        approval.setTargetDeptId(dto.getTargetDeptId());
        approval.setStartDate(dto.getStartDate());
        approval.setEndDate(dto.getEndDate());
        approval.setPriority(dto.getPriority() != null ? dto.getPriority() : 0);
        approval.setStatus(0); // 待审批
        approval.setApprovalLevel(1); // 从班主任初审开始
        approval.setApplyTime(LocalDateTime.now());
        
        // 确定当前审批人（学生所在班级的班主任）
        Classes studentClass = classesMapper.selectById(student.getClassId());
        if (studentClass != null && studentClass.getHeadTeacherId() != null) {
            approval.setCurrentApproverId(studentClass.getHeadTeacherId());
        }
        
        approvalMapper.insert(approval);
        
        // 发送通知给班主任
        if (approval.getCurrentApproverId() != null) {
            messageService.sendMessage(
                approval.getCurrentApproverId(),
                "approval",
                "新的审批申请",
                "学生" + getStudentName(student) + "提交了" + getSubTypeName(dto.getSubType()) + "申请，请及时审批。",
                approval.getId()
            );
        }
        
        log.info("学生异动申请提交成功：userId={}, studentId={}, subType={}, approvalId={}", 
                userId, studentId, dto.getSubType(), approval.getId());
        
        return approval.getId();
    }
    
    /**
     * 处理审批（初审/终审）
     */
    @Transactional(rollbackFor = Exception.class)
    public void processApproval(ApprovalProcessDTO dto) {
        Approval approval = approvalMapper.selectById(dto.getApprovalId());
        if (approval == null) {
            throw new BusinessException("审批记录不存在");
        }
        
        if (approval.getStatus() != 0) {
            throw new BusinessException("该申请已处理");
        }
        
        Long currentUserId = StpUtil.getLoginIdAsLong();
        
        // 验证当前用户是否有权限审批
        if (approval.getCurrentApproverId() != null && 
            !approval.getCurrentApproverId().equals(currentUserId)) {
            // 如果不是指定审批人，检查是否是管理员
            List<String> roles = StpUtil.getRoleList();
            if (!roles.contains("admin")) {
                throw new BusinessException("您无权审批此申请");
            }
        }
        
        // 记录历史审批意见
        recordHistoryOpinion(approval, currentUserId, dto.getAction(), dto.getOpinion());
        
        if (dto.getAction() == 1) {
            // 同意
            handleApprove(approval, currentUserId, dto.getOpinion());
        } else if (dto.getAction() == 2) {
            // 拒绝
            handleReject(approval, currentUserId, dto.getOpinion());
        } else if (dto.getAction() == 3) {
            // 转交
            handleTransfer(approval, currentUserId, dto.getOpinion(), dto.getNextApproverId());
        }
        
        approvalMapper.updateById(approval);
        
        // 清除审批详情缓存
        redisService.delete(CACHE_KEY_APPROVAL_DETAIL + approval.getId());
        
        log.info("审批处理完成：approvalId={}, action={}, level={}", 
                dto.getApprovalId(), dto.getAction(), approval.getApprovalLevel());
    }
    
    /**
     * 处理同意操作
     */
    private void handleApprove(Approval approval, Long approverId, String opinion) {
        approval.setRemark(opinion);
        
        if (approval.getApprovalLevel() == 1) {
            // 班主任初审通过，流转到教务处终审
            approval.setApprovalLevel(2);
            approval.setCurrentApproverId(null); // 教务处（管理员角色）
            
            // 通知教务处有新的审批
            messageService.sendMessageToRole(
                "admin",
                "approval",
                "新的审批待处理",
                "班主任已初审通过" + getSubTypeName(approval.getSubType()) + "申请，请进行终审。",
                approval.getId()
            );
            
            // 通知学生初审已通过
            Student student = studentMapper.selectById(approval.getStudentId());
            if (student != null && student.getUserId() != null) {
                messageService.sendMessage(
                    student.getUserId(),
                    "approval",
                    "审批进度更新",
                    "您的" + getSubTypeName(approval.getSubType()) + "申请班主任已初审通过，正在等待教务处终审。",
                    approval.getId()
                );
            }
            
        } else if (approval.getApprovalLevel() == 2) {
            // 教务处终审通过，申请完成
            approval.setStatus(1); // 已通过
            approval.setApproverId(approverId);
            approval.setApproveTime(LocalDateTime.now());
            
            // 自动更新学生状态
            updateStudentStatus(approval);
            
            // 记录异动历史
            recordStatusChange(approval);
            
            // 通知学生申请已通过
            Student student = studentMapper.selectById(approval.getStudentId());
            if (student != null && student.getUserId() != null) {
                messageService.sendMessage(
                    student.getUserId(),
                    "approval",
                    "申请审批通过",
                    "恭喜！您的" + getSubTypeName(approval.getSubType()) + "申请已审批通过。" + 
                    (opinion != null && !opinion.isEmpty() ? "审批意见：" + opinion : ""),
                    approval.getId()
                );
            }
        }
    }
    
    /**
     * 处理拒绝操作
     */
    private void handleReject(Approval approval, Long approverId, String opinion) {
        if (opinion == null || opinion.trim().isEmpty()) {
            throw new BusinessException("拒绝时必须填写意见");
        }
        
        approval.setStatus(2); // 已拒绝
        approval.setRemark(opinion);
        approval.setApproverId(approverId);
        approval.setApproveTime(LocalDateTime.now());
        
        // 通知学生申请被拒绝
        Student student = studentMapper.selectById(approval.getStudentId());
        if (student != null && student.getUserId() != null) {
            messageService.sendMessage(
                student.getUserId(),
                "approval",
                "申请审批未通过",
                "抱歉，您的" + getSubTypeName(approval.getSubType()) + "申请未通过审批。拒绝原因：" + opinion,
                approval.getId()
            );
        }
    }
    
    /**
     * 处理转交操作
     */
    private void handleTransfer(Approval approval, Long approverId, String opinion, Long nextApproverId) {
        if (nextApproverId == null) {
            throw new BusinessException("转交时必须指定下一审批人");
        }
        
        approval.setCurrentApproverId(nextApproverId);
        approval.setRemark(opinion);
        
        // 通知下一审批人
        messageService.sendMessage(
            nextApproverId,
            "approval",
            "审批已转交给您",
            "有一个" + getSubTypeName(approval.getSubType()) + "申请已转交给您处理。" +
            (opinion != null && !opinion.isEmpty() ? "转交说明：" + opinion : ""),
            approval.getId()
        );
    }
    
    /**
     * 获取我的待审批列表
     */
    public PageResult<ApprovalVO> getMyPendingApprovals(Integer current, Integer size) {
        Long userId = StpUtil.getLoginIdAsLong();
        List<String> roles = StpUtil.getRoleList();
        
        Page<Approval> page = new Page<>(current, size);
        LambdaQueryWrapper<Approval> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Approval::getStatus, 0); // 待审批
        
        if (roles.contains("admin")) {
            // 管理员：查看所有二级审批（教务处终审）
            wrapper.eq(Approval::getApprovalLevel, 2);
        } else {
            // 普通用户：只查看分配给自己的
            wrapper.eq(Approval::getCurrentApproverId, userId);
        }
        
        wrapper.orderByDesc(Approval::getPriority);
        wrapper.orderByDesc(Approval::getApplyTime);
        
        IPage<Approval> approvalPage = approvalMapper.selectPage(page, wrapper);
        List<ApprovalVO> voList = convertToVO(approvalPage.getRecords());
        
        return new PageResult<>(approvalPage.getTotal(), voList);
    }
    
    /**
     * 学生查询自己的申请记录
     */
    public PageResult<ApprovalVO> getMyApplies(Integer current, Integer size, String subType, Integer status) {
        // 获取当前登录用户ID
        Long userId = StpUtil.getLoginIdAsLong();
        log.info("userId: {}", userId);
        
        // 根据userId查找对应的学生记录
        LambdaQueryWrapper<Student> studentWrapper = new LambdaQueryWrapper<>();
        studentWrapper.eq(Student::getUserId, userId);
        Student student = studentMapper.selectOne(studentWrapper);
        
        if (student == null) {
            throw new BusinessException("未找到学生信息");
        }
        
        // 分页查询该学生的所有申请
        Page<Approval> page = new Page<>(current, size);
        LambdaQueryWrapper<Approval> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Approval::getStudentId, student.getId()); // 只查询该学生的申请
        wrapper.eq(Approval::getApplyType, 1); // 学籍异动申请
        wrapper.eq(subType != null && !subType.isEmpty(), Approval::getSubType, subType);
        wrapper.eq(status != null, Approval::getStatus, status);
        wrapper.orderByDesc(Approval::getApplyTime);
        
        IPage<Approval> approvalPage = approvalMapper.selectPage(page, wrapper);
        List<ApprovalVO> voList = convertToVO(approvalPage.getRecords());
        
        return new PageResult<>(approvalPage.getTotal(), voList);
    }
    
    /**
     * 撤回申请（只能撤回待审批的申请）
     */
    @Transactional(rollbackFor = Exception.class)
    public void cancelApproval(Long id) {
        Approval approval = approvalMapper.selectById(id);
        if (approval == null) {
            throw new BusinessException("申请不存在");
        }
        
        // 只能撤回待审批的申请
        if (approval.getStatus() != 0) {
            throw new BusinessException("只能撤回待审批的申请");
        }
        
        // 检查权限：只有申请人可以撤回
        Long currentUserId = StpUtil.getLoginIdAsLong();
        Student student = studentMapper.selectById(approval.getStudentId());
        if (student == null || !student.getUserId().equals(currentUserId)) {
            throw new BusinessException("无权撤回此申请");
        }
        
        // 更新状态为已撤回（可以用status=3表示撤回）
        approval.setStatus(3); // 3-已撤回
        approval.setRemark("学生主动撤回");
        approvalMapper.updateById(approval);
        
        // 通知审批人
        if (approval.getCurrentApproverId() != null) {
            messageService.sendMessage(
                approval.getCurrentApproverId(),
                "approval",
                "申请已撤回",
                "学生" + getStudentName(student) + "撤回了" + getSubTypeName(approval.getSubType()) + "申请。",
                approval.getId()
            );
        }
        
        log.info("撤回申请成功：approvalId={}", id);
    }
    
    /**
     * 获取审批详情（带缓存）
     */
    public ApprovalDetailVO getApprovalDetail(Long id) {
        String cacheKey = CACHE_KEY_APPROVAL_DETAIL + id;
        
        // 先从缓存中获取
        Object cached = redisService.get(cacheKey);
        if (cached != null) {
            log.debug("从缓存中获取审批详情：id={}", id);
            return (ApprovalDetailVO) cached;
        }
        
        // 缓存未命中，从数据库查询
        Approval approval = approvalMapper.selectById(id);
        if (approval == null) {
            throw new BusinessException("审批记录不存在");
        }
        
        ApprovalDetailVO detailVO = new ApprovalDetailVO();
        BeanUtils.copyProperties(approval, detailVO);
        
        // 设置名称
        detailVO.setApplyTypeName(getApplyTypeName(approval.getApplyType()));
        detailVO.setSubTypeName(getSubTypeName(approval.getSubType()));
        detailVO.setApprovalLevelName(getApprovalLevelName(approval.getApprovalLevel()));
        detailVO.setPriorityName(getPriorityName(approval.getPriority()));
        detailVO.setStatusName(getStatusName(approval.getStatus()));
        
        // 查询学生信息
        Student student = studentMapper.selectById(approval.getStudentId());
        if (student != null) {
            detailVO.setStudentNo(student.getStudentNo());
            detailVO.setGender(student.getGender() != null ? student.getGender().toString() : null);
            // 从enrollDate中提取入学年份
            if (student.getEnrollDate() != null) {
                detailVO.setEnrollYear(student.getEnrollDate().getYear());
            }
            detailVO.setStudentStatus(student.getStatus());
            detailVO.setStudentStatusName(getStudentStatusName(student.getStatus()));
            
            // 学生姓名
            if (student.getUserId() != null) {
                SysUser user = userMapper.selectById(student.getUserId());
                if (user != null) {
                    detailVO.setStudentName(user.getRealName());
                }
            }
            
            // 院系班级信息
            if (student.getDeptId() != null) {
                Dept dept = deptMapper.selectById(student.getDeptId());
                if (dept != null) {
                    detailVO.setDeptName(dept.getDeptName());
                }
            }
            
            if (student.getClassId() != null) {
                Classes classes = classesMapper.selectById(student.getClassId());
                if (classes != null) {
                    detailVO.setClassName(classes.getClassName());
                }
            }
        }
        
        // 目标班级院系信息
        if (approval.getTargetClassId() != null) {
            Classes targetClass = classesMapper.selectById(approval.getTargetClassId());
            if (targetClass != null) {
                detailVO.setTargetClassName(targetClass.getClassName());
            }
        }
        
        if (approval.getTargetDeptId() != null) {
            Dept targetDept = deptMapper.selectById(approval.getTargetDeptId());
            if (targetDept != null) {
                detailVO.setTargetDeptName(targetDept.getDeptName());
            }
        }
        
        // 当前审批人
        if (approval.getCurrentApproverId() != null) {
            SysUser approver = userMapper.selectById(approval.getCurrentApproverId());
            if (approver != null) {
                detailVO.setCurrentApproverName(approver.getRealName());
            }
        }
        
        // 最终审批人
        if (approval.getApproverId() != null) {
            SysUser finalApprover = userMapper.selectById(approval.getApproverId());
            if (finalApprover != null) {
                detailVO.setApproverName(finalApprover.getRealName());
            }
        }
        
        // 附件列表
        if (approval.getAttachmentIds() != null && !approval.getAttachmentIds().isEmpty()) {
            String[] fileIds = approval.getAttachmentIds().split(",");
            List<FileInfoVO> attachments = new ArrayList<>();
            for (String fileIdStr : fileIds) {
                try {
                    Long fileId = Long.parseLong(fileIdStr.trim());
                    FileInfoVO fileInfo = fileService.getFileDetail(fileId);
                    attachments.add(fileInfo);
                } catch (Exception e) {
                    log.error("加载附件失败：fileId={}", fileIdStr, e);
                }
            }
            detailVO.setAttachments(attachments);
        }
        
        // 解析历史审批意见
        if (approval.getHistoryOpinion() != null && !approval.getHistoryOpinion().isEmpty()) {
            try {
                JSONArray historyArray = JSON.parseArray(approval.getHistoryOpinion());
                List<ApprovalDetailVO.ApprovalOpinion> opinions = new ArrayList<>();
                
                for (int i = 0; i < historyArray.size(); i++) {
                    JSONObject obj = historyArray.getJSONObject(i);
                    ApprovalDetailVO.ApprovalOpinion opinion = new ApprovalDetailVO.ApprovalOpinion();
                    opinion.setLevel(obj.getInteger("level"));
                    opinion.setLevelName(getApprovalLevelName(obj.getInteger("level")));
                    opinion.setApproverName(obj.getString("approverName"));
                    opinion.setAction(obj.getInteger("action"));
                    opinion.setActionName(getActionName(obj.getInteger("action")));
                    opinion.setOpinion(obj.getString("opinion"));
                    opinion.setApproveTime(obj.getObject("approveTime", LocalDateTime.class));
                    opinions.add(opinion);
                }
                
                detailVO.setHistoryOpinions(opinions);
            } catch (Exception e) {
                log.error("解析历史审批意见失败", e);
            }
        }
        
        // 存入缓存（10分钟，审批信息可能频繁变化）
        redisService.set(cacheKey, detailVO, 10, java.util.concurrent.TimeUnit.MINUTES);
        log.debug("将审批详情存入缓存：id={}", id);
        
        return detailVO;
    }
    
    // ========== 私有辅助方法 ==========
    
    /**
     * 记录历史审批意见
     */
    private void recordHistoryOpinion(Approval approval, Long approverId, Integer action, String opinion) {
        JSONArray historyArray;
        if (approval.getHistoryOpinion() != null && !approval.getHistoryOpinion().isEmpty()) {
            historyArray = JSON.parseArray(approval.getHistoryOpinion());
        } else {
            historyArray = new JSONArray();
        }
        
        JSONObject newOpinion = new JSONObject();
        newOpinion.put("level", approval.getApprovalLevel());
        newOpinion.put("approverId", approverId);
        
        SysUser approver = userMapper.selectById(approverId);
        newOpinion.put("approverName", approver != null ? approver.getRealName() : "未知");
        
        newOpinion.put("action", action);
        newOpinion.put("opinion", opinion);
        newOpinion.put("approveTime", LocalDateTime.now());
        
        historyArray.add(newOpinion);
        approval.setHistoryOpinion(historyArray.toJSONString());
    }
    
    /**
     * 自动更新学生状态
     */
    private void updateStudentStatus(Approval approval) {
        Student student = studentMapper.selectById(approval.getStudentId());
        if (student == null) {
            return;
        }
        
        Integer oldStatus = student.getStatus();
        String subType = approval.getSubType();
        
        if ("suspension".equals(subType)) {
            // 休学：状态改为2-休学
            student.setStatus(2);
        } else if ("return".equals(subType)) {
            // 复学：状态改为1-在籍
            student.setStatus(1);
        } else if ("dropout".equals(subType)) {
            // 退学：状态改为4-退学
            student.setStatus(4);
        } else if ("transfer".equals(subType)) {
            // 转学：更新班级和院系
            if (approval.getTargetClassId() != null) {
                student.setClassId(approval.getTargetClassId());
            }
            if (approval.getTargetDeptId() != null) {
                student.setDeptId(approval.getTargetDeptId());
            }
        }
        
        studentMapper.updateById(student);
        
        log.info("学生状态已更新：studentId={}, oldStatus={}, newStatus={}", 
                student.getId(), oldStatus, student.getStatus());
    }
    
    /**
     * 记录异动历史
     */
    private void recordStatusChange(Approval approval) {
        Student student = studentMapper.selectById(approval.getStudentId());
        if (student == null) {
            return;
        }
        
        StudentStatusChange statusChange = new StudentStatusChange();
        statusChange.setStudentId(approval.getStudentId());
        statusChange.setChangeType(approval.getSubType());
        statusChange.setReason(approval.getContent());
        statusChange.setApprovalId(approval.getId());
        statusChange.setOperatorId(approval.getApproverId());
        statusChange.setChangeTime(LocalDateTime.now());
        
        // 根据类型设置状态变更
        if ("suspension".equals(approval.getSubType())) {
            statusChange.setOldStatus(1);
            statusChange.setNewStatus(2);
        } else if ("return".equals(approval.getSubType())) {
            statusChange.setOldStatus(2);
            statusChange.setNewStatus(1);
        } else if ("dropout".equals(approval.getSubType())) {
            statusChange.setOldStatus(student.getStatus());
            statusChange.setNewStatus(4);
        } else if ("transfer".equals(approval.getSubType())) {
            statusChange.setOldClassId(student.getClassId());
            statusChange.setNewClassId(approval.getTargetClassId());
            statusChange.setOldDeptId(student.getDeptId());
            statusChange.setNewDeptId(approval.getTargetDeptId());
        }
        
        statusChangeMapper.insert(statusChange);
        
        log.info("异动历史已记录：studentId={}, changeType={}", 
                approval.getStudentId(), approval.getSubType());
    }
    
    private String getStudentName(Student student) {
        if (student.getUserId() == null) {
            return "学号" + student.getStudentNo();
        }
        SysUser user = userMapper.selectById(student.getUserId());
        return user != null ? user.getRealName() : "学号" + student.getStudentNo();
    }
    
    private String getApplyTypeName(Integer type) {
        if (type == null) return "未知";
        switch (type) {
            case 1: return "学籍异动";
            case 2: return "信息修改";
            case 3: return "档案附件";
            default: return "未知";
        }
    }
    
    private String getSubTypeName(String subType) {
        if (subType == null) return "未知";
        Map<String, String> map = new HashMap<>();
        map.put("suspension", "休学");
        map.put("transfer", "转学");
        map.put("return", "复学");
        map.put("dropout", "退学");
        map.put("info_modify", "信息修改");
        map.put("file_audit", "附件审核");
        return map.getOrDefault(subType, subType);
    }
    
    private String getApprovalLevelName(Integer level) {
        if (level == null) return "未知";
        switch (level) {
            case 1: return "班主任初审";
            case 2: return "教务处终审";
            default: return "未知";
        }
    }
    
    private String getPriorityName(Integer priority) {
        if (priority == null) return "普通";
        switch (priority) {
            case 0: return "普通";
            case 1: return "重要";
            case 2: return "紧急";
            default: return "普通";
        }
    }
    
    private String getStatusName(Integer status) {
        if (status == null) return "未知";
        switch (status) {
            case 0: return "待审批";
            case 1: return "已通过";
            case 2: return "已拒绝";
            default: return "未知";
        }
    }
    
    private String getStudentStatusName(Integer status) {
        if (status == null) return "未知";
        switch (status) {
            case 1: return "在籍";
            case 2: return "休学";
            case 3: return "毕业";
            case 4: return "退学";
            default: return "未知";
        }
    }
    
    private String getActionName(Integer action) {
        if (action == null) return "未知";
        switch (action) {
            case 1: return "同意";
            case 2: return "拒绝";
            case 3: return "转交";
            default: return "未知";
        }
    }
}

